Introduction

This is an analysis of the responses to Kaggle’s 2017 user survey. In total, 16,716 people responded to enough of the survey to be analyzed. Allow to this survey and this following analysis, we can know how to manage and launch a data science team.

Data Source

All data was collected by Kaggle in their 2017 user survey. The survey was available to users from August 7 - August 25, 2017.

Inspired by this kernel

Installing Necessary Packages

# For Data Cleaning
library(tidyverse)
library(ggplot2)
library(plotly)
# For text analysis and word clouds
library(tm)
library(SnowballC)
library(wordcloud)

Loading Data

Based on the way this data is structured, I want to keep the first row as column headers.

# Import multiple choice data
Survey <- read.csv('../input/multipleChoiceResponses.csv', stringsAsFactors = TRUE, header = TRUE)
# Import freeform responses
rawFFData <- read.csv('../input/freeformResponses.csv', stringsAsFactors = FALSE, header = TRUE)
# Import the actual questions asked
schema <- read.csv('../input/schema.csv', stringsAsFactors = FALSE, header = TRUE)

Last, I need to import the currency conversion rates for use later.

conversionRates <- read.csv('../input/conversionRates.csv', header = TRUE)

Basic clean data

Id

We’re creating an id column. It will use later

Survey = Survey %>% 
  mutate(id = 1:nrow(Survey))

Age

We have to cut the age in order to analyse easiest possible.

Survey$Age <- as.numeric(as.character(Survey$Age))
ggplot(Survey,aes(Age)) +
  geom_histogram(bins = 100,color = "blue")

breaks_Age = c(min(Survey$Age,na.rm = T),"20","25","30","45",max(Survey$Age,na.rm = T))
Survey$Age = cut(Survey$Age,breaks_Age,include.lowest = TRUE)

What kind of company works ?

size

Where launch your futur company ?

map

What kind of equipment use ?

computer ## Where can you find data scientist ? School Reconversion

df = Survey %>% 
  select(CurrentJobTitleSelect) %>% 
  group_by(CurrentJobTitleSelect) %>% 
  summarise(count = n()) %>% 
  arrange(desc(count)) %>% 
  filter(CurrentJobTitleSelect != "")
  
custom_text = sprintf("Job: %s <b> freq : %d",df$CurrentJobTitleSelect,df$count)
p = ggplot(df,aes(x = reorder(CurrentJobTitleSelect,-count),y = count,fill = reorder(CurrentJobTitleSelect,-count),text = custom_text))+
  geom_bar(stat = "identity")
ggplotly(p,tooltip = "text")
We recommend that you use the dev version of ggplot2 with `ggplotly()`
Install it with: `devtools::install_github('hadley/ggplot2')`
foo = Survey %>% 
  select(Age,CurrentJobTitleSelect,DataScienceIdentitySelect) %>% 
  filter(CurrentJobTitleSelect != "") %>% 
  filter(DataScienceIdentitySelect != "") %>% 
  filter(CurrentJobTitleSelect %in% df$CurrentJobTitleSelect[1:10]) %>% 
  ungroup() %>% 
  filter(complete.cases(.)) %>% 
  group_by(Age,CurrentJobTitleSelect,DataScienceIdentitySelect) %>% 
  summarise(count = n()) %>% 
  droplevels()
alluvial(foo[,1:3], freq=foo$count,
         col = ifelse(foo$DataScienceIdentitySelect == "Yes", "orange", "grey"),
         border = ifelse(foo$DataScienceIdentitySelect == "Yes", "orange", "grey"),
         cex = 0.7
)

DS = Survey$id[which(Survey$DataScienceIdentitySelect == "Yes")]
DS = c(DS,Survey$id[which(Survey$CurrentJobTitleSelect == "Data Scientist")])
foo = Survey %>% 
  mutate(IsDS = id %in% DS) %>% 
  select(FormalEducation,MajorSelect,CurrentJobTitleSelect,IsDS) %>% 
  filter(CurrentJobTitleSelect != "") %>% 
  filter(FormalEducation != "") %>% 
  filter(MajorSelect != "") %>% 
  #filter(CurrentJobTitleSelect %in% df$CurrentJobTitleSelect[1:10]) %>% 
  ungroup() %>% 
  filter(complete.cases(.)) %>% 
  group_by(FormalEducation,MajorSelect,CurrentJobTitleSelect,IsDS) %>% 
  summarise(count = n()) %>% 
  filter(count > 50) %>% 
  droplevels()
alluvial(foo[,1:4], freq=foo$count,
         col = ifelse(foo$IsDS == "FALSE", "orange", "grey"),
         border = ifelse(foo$IsDS == "FALSE", "orange", "grey"),
         #hide = foo$count < 50,
         cex = 0.7
)

This graph can help you to know where you can find DS. For example : - Most of the bachelor’s degree are not DS - A good Software Developer with a Doctoral degree can be as DS. Otherwise, it’s not a DS.

How can you form your data scientist ?

Skills

recommendations <- Survey %>% 
  # Remove any non-entries for either question
  filter(!WorkToolsSelect == "") %>% 
  filter(!LanguageRecommendationSelect == "") %>% 
  # Select only the columns for the language recommendations and language use
  select(WorkToolsSelect, LanguageRecommendationSelect) %>% 
  # Split the language usage column at the comma
  mutate(WorkToolsSelect = strsplit(as.character(WorkToolsSelect), '\\([^)]+,(*SKIP)(*FAIL)|,\\s*', perl = TRUE)) %>% 
  # Split answers are now nested, need to unnest them
  unnest(WorkToolsSelect) %>% 
  # Group by language used and then by recommendation
  group_by(WorkToolsSelect, LanguageRecommendationSelect) %>% 
  # Rename the columns
  rename(Used = WorkToolsSelect, Recommended = LanguageRecommendationSelect) %>% 
  # Count the number of responses for each language use/recommendation combination
  summarise(count = n()) %>% 
  filter(count >300) 
  

# Display the results
recommendations$Used = as.factor(recommendations$Used)
recommendations = recommendations %>%
  droplevels()
circos.clear()
chordDiagram(recommendations,annotationTrack = "grid",,preAllocateTracks = 1) 
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5), cex=.6)
  # circos.axis(h = "top", labels.cex = 0.5, major.tick.percentage = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

As you can see, most of them use Python and R. If they have to recommand it, most of them choose Pyhton. The cirle show that most of the people work with other that R and python, they recommand it python and R.

We can look up which technologies were considered to be the most important on the job. Here, I plotted popularity against usefulness again to see which technologies are used the most in the real world.

With this graph, we can understand that Python is the most useful and popular skill. The second one is Stats, then BigData, R, SQL and Visualizations.

Now you know which skills are important for your data scientist, you need to know HOW to learn it. You can provide them some plateform. Let’s see the most usefulness :

Plateform

So, you can propose them Kaggle, Courses, Stack Overflow and Projects.

Which data scientist are happy ?

Which salary give on your data scientist ?

predict the salary (model regression)

LS0tCnRpdGxlOiAiU3RhcnRlciBTdXJ2ZXkgMjAxNyIKYXV0aG9yOiAiSHVnbyBTRUNISUVSIgpkYXRlOiAiTm92ZW1iZXIgMywgMjAxNyIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgaGlnaGxpZ2h0OiBoYWRkb2NrCiAgICB0aGVtZTogcmVhZGFibGUKLS0tCgoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgaXMgYW4gYW5hbHlzaXMgb2YgdGhlIHJlc3BvbnNlcyB0byBLYWdnbGUncyAyMDE3IHVzZXIgc3VydmV5LiBJbiB0b3RhbCwgMTYsNzE2IHBlb3BsZSByZXNwb25kZWQgdG8gZW5vdWdoIG9mIHRoZSBzdXJ2ZXkgdG8gYmUgYW5hbHl6ZWQuIApBbGxvdyB0byB0aGlzIHN1cnZleSBhbmQgdGhpcyBmb2xsb3dpbmcgYW5hbHlzaXMsIHdlIGNhbiBrbm93IGhvdyB0byBtYW5hZ2UgYW5kIGxhdW5jaCBhIGRhdGEgc2NpZW5jZSB0ZWFtLiAKCiMjIERhdGEgU291cmNlCgpBbGwgZGF0YSB3YXMgY29sbGVjdGVkIGJ5IFtLYWdnbGVdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20pIGluIHRoZWlyIDIwMTcgdXNlciBzdXJ2ZXkuIFRoZSBzdXJ2ZXkgd2FzIGF2YWlsYWJsZSB0byB1c2VycyBmcm9tIEF1Z3VzdCA3IC0gQXVndXN0IDI1LCAyMDE3LiAKCkluc3BpcmVkIGJ5IFt0aGlzIGtlcm5lbF0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9hbWJlcnRob21hcy9rYWdnbGUtMjAxNy1zdXJ2ZXktcmVzdWx0cykKCiMjIEluc3RhbGxpbmcgTmVjZXNzYXJ5IFBhY2thZ2VzCgpgYGB7cn0KIyBGb3IgRGF0YSBDbGVhbmluZwpsaWJyYXJ5KHRpZHl2ZXJzZSkKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoYWxsdXZpYWwpCmxpYnJhcnkoY2lyY2xpemUpCiMgRm9yIHRleHQgYW5hbHlzaXMgYW5kIHdvcmQgY2xvdWRzCmxpYnJhcnkodG0pCmxpYnJhcnkoU25vd2JhbGxDKQpsaWJyYXJ5KHdvcmRjbG91ZCkKCmBgYAoKIyMgTG9hZGluZyBEYXRhCgpCYXNlZCBvbiB0aGUgd2F5IHRoaXMgZGF0YSBpcyBzdHJ1Y3R1cmVkLCBJIHdhbnQgdG8ga2VlcCB0aGUgZmlyc3Qgcm93IGFzIGNvbHVtbiBoZWFkZXJzLiAKCmBgYHtyfQojIEltcG9ydCBtdWx0aXBsZSBjaG9pY2UgZGF0YQpTdXJ2ZXkgPC0gcmVhZC5jc3YoJy4uL2lucHV0L211bHRpcGxlQ2hvaWNlUmVzcG9uc2VzLmNzdicsIHN0cmluZ3NBc0ZhY3RvcnMgPSBUUlVFLCBoZWFkZXIgPSBUUlVFKQoKIyBJbXBvcnQgZnJlZWZvcm0gcmVzcG9uc2VzCnJhd0ZGRGF0YSA8LSByZWFkLmNzdignLi4vaW5wdXQvZnJlZWZvcm1SZXNwb25zZXMuY3N2Jywgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBoZWFkZXIgPSBUUlVFKQoKIyBJbXBvcnQgdGhlIGFjdHVhbCBxdWVzdGlvbnMgYXNrZWQKc2NoZW1hIDwtIHJlYWQuY3N2KCcuLi9pbnB1dC9zY2hlbWEuY3N2Jywgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBoZWFkZXIgPSBUUlVFKQpgYGAKCkxhc3QsIEkgbmVlZCB0byBpbXBvcnQgdGhlIGN1cnJlbmN5IGNvbnZlcnNpb24gcmF0ZXMgZm9yIHVzZSBsYXRlci4gCmBgYHtyfQpjb252ZXJzaW9uUmF0ZXMgPC0gcmVhZC5jc3YoJy4uL2lucHV0L2NvbnZlcnNpb25SYXRlcy5jc3YnLCBoZWFkZXIgPSBUUlVFKQpgYGAKIyMgQmFzaWMgY2xlYW4gZGF0YSAKIyMjIElkIApXZSdyZSBjcmVhdGluZyBhbiBpZCBjb2x1bW4uIEl0IHdpbGwgdXNlIGxhdGVyIApgYGB7cn0KU3VydmV5ID0gU3VydmV5ICU+JSAKICBtdXRhdGUoaWQgPSAxOm5yb3coU3VydmV5KSkKYGBgCgojIyMgQWdlIApXZSBoYXZlIHRvIGN1dCB0aGUgYWdlIGluIG9yZGVyIHRvIGFuYWx5c2UgZWFzaWVzdCBwb3NzaWJsZS4gCgpgYGB7cn0KU3VydmV5JEFnZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihTdXJ2ZXkkQWdlKSkKZ2dwbG90KFN1cnZleSxhZXMoQWdlKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMDAsY29sb3IgPSAiYmx1ZSIpCmBgYApgYGB7cn0KYnJlYWtzX0FnZSA9IGMobWluKFN1cnZleSRBZ2UsbmEucm0gPSBUKSwiMjAiLCIyNSIsIjMwIiwiNDUiLG1heChTdXJ2ZXkkQWdlLG5hLnJtID0gVCkpClN1cnZleSRBZ2UgPSBjdXQoU3VydmV5JEFnZSxicmVha3NfQWdlLGluY2x1ZGUubG93ZXN0ID0gVFJVRSkKYGBgCgoKCgoKIyMgV2hhdCBraW5kIG9mIGNvbXBhbnkgd29ya3MgPyAKc2l6ZQoKIyMgV2hlcmUgbGF1bmNoIHlvdXIgZnV0dXIgY29tcGFueSA/IAptYXAKCiMjIFdoYXQga2luZCBvZiBlcXVpcG1lbnQgdXNlID8gCmNvbXB1dGVyCiMjIFdoZXJlIGNhbiB5b3UgZmluZCBkYXRhIHNjaWVudGlzdCA/IApTY2hvb2wgClJlY29udmVyc2lvbiAKCmBgYHtyfQpkZiA9IFN1cnZleSAlPiUgCiAgc2VsZWN0KEN1cnJlbnRKb2JUaXRsZVNlbGVjdCkgJT4lIAogIGdyb3VwX2J5KEN1cnJlbnRKb2JUaXRsZVNlbGVjdCkgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjb3VudCkpICU+JSAKICBmaWx0ZXIoQ3VycmVudEpvYlRpdGxlU2VsZWN0ICE9ICIiKQogIApjdXN0b21fdGV4dCA9IHNwcmludGYoIkpvYjogJXMgPGI+IGZyZXEgOiAlZCIsZGYkQ3VycmVudEpvYlRpdGxlU2VsZWN0LGRmJGNvdW50KQpwID0gZ2dwbG90KGRmLGFlcyh4ID0gcmVvcmRlcihDdXJyZW50Sm9iVGl0bGVTZWxlY3QsLWNvdW50KSx5ID0gY291bnQsZmlsbCA9IHJlb3JkZXIoQ3VycmVudEpvYlRpdGxlU2VsZWN0LC1jb3VudCksdGV4dCA9IGN1c3RvbV90ZXh0KSkrCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpCmdncGxvdGx5KHAsdG9vbHRpcCA9ICJ0ZXh0IikKYGBgCgoKYGBge3J9CmZvbyA9IFN1cnZleSAlPiUgCiAgc2VsZWN0KEFnZSxDdXJyZW50Sm9iVGl0bGVTZWxlY3QsRGF0YVNjaWVuY2VJZGVudGl0eVNlbGVjdCkgJT4lIAogIGZpbHRlcihDdXJyZW50Sm9iVGl0bGVTZWxlY3QgIT0gIiIpICU+JSAKICBmaWx0ZXIoRGF0YVNjaWVuY2VJZGVudGl0eVNlbGVjdCAhPSAiIikgJT4lIAogIGZpbHRlcihDdXJyZW50Sm9iVGl0bGVTZWxlY3QgJWluJSBkZiRDdXJyZW50Sm9iVGl0bGVTZWxlY3RbMToxMF0pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGZpbHRlcihjb21wbGV0ZS5jYXNlcyguKSkgJT4lIAogIGdyb3VwX2J5KEFnZSxDdXJyZW50Sm9iVGl0bGVTZWxlY3QsRGF0YVNjaWVuY2VJZGVudGl0eVNlbGVjdCkgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGRyb3BsZXZlbHMoKQoKYWxsdXZpYWwoZm9vWywxOjNdLCBmcmVxPWZvbyRjb3VudCwKICAgICAgICAgY29sID0gaWZlbHNlKGZvbyREYXRhU2NpZW5jZUlkZW50aXR5U2VsZWN0ID09ICJZZXMiLCAib3JhbmdlIiwgImdyZXkiKSwKICAgICAgICAgYm9yZGVyID0gaWZlbHNlKGZvbyREYXRhU2NpZW5jZUlkZW50aXR5U2VsZWN0ID09ICJZZXMiLCAib3JhbmdlIiwgImdyZXkiKSwKICAgICAgICAgY2V4ID0gMC43CikKCmBgYAoKCmBgYHtyfQpEUyA9IFN1cnZleSRpZFt3aGljaChTdXJ2ZXkkRGF0YVNjaWVuY2VJZGVudGl0eVNlbGVjdCA9PSAiWWVzIildCkRTID0gYyhEUyxTdXJ2ZXkkaWRbd2hpY2goU3VydmV5JEN1cnJlbnRKb2JUaXRsZVNlbGVjdCA9PSAiRGF0YSBTY2llbnRpc3QiKV0pCmZvbyA9IFN1cnZleSAlPiUgCiAgbXV0YXRlKElzRFMgPSBpZCAlaW4lIERTKSAlPiUgCiAgc2VsZWN0KEZvcm1hbEVkdWNhdGlvbixNYWpvclNlbGVjdCxDdXJyZW50Sm9iVGl0bGVTZWxlY3QsSXNEUykgJT4lIAogIGZpbHRlcihDdXJyZW50Sm9iVGl0bGVTZWxlY3QgIT0gIiIpICU+JSAKICBmaWx0ZXIoRm9ybWFsRWR1Y2F0aW9uICE9ICIiKSAlPiUgCiAgZmlsdGVyKE1ham9yU2VsZWN0ICE9ICIiKSAlPiUgCiAgI2ZpbHRlcihDdXJyZW50Sm9iVGl0bGVTZWxlY3QgJWluJSBkZiRDdXJyZW50Sm9iVGl0bGVTZWxlY3RbMToxMF0pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGZpbHRlcihjb21wbGV0ZS5jYXNlcyguKSkgJT4lIAogIGdyb3VwX2J5KEZvcm1hbEVkdWNhdGlvbixNYWpvclNlbGVjdCxDdXJyZW50Sm9iVGl0bGVTZWxlY3QsSXNEUykgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGZpbHRlcihjb3VudCA+IDUwKSAlPiUgCiAgZHJvcGxldmVscygpCgphbGx1dmlhbChmb29bLDE6NF0sIGZyZXE9Zm9vJGNvdW50LAogICAgICAgICBjb2wgPSBpZmVsc2UoZm9vJElzRFMgPT0gIkZBTFNFIiwgIm9yYW5nZSIsICJncmV5IiksCiAgICAgICAgIGJvcmRlciA9IGlmZWxzZShmb28kSXNEUyA9PSAiRkFMU0UiLCAib3JhbmdlIiwgImdyZXkiKSwKICAgICAgICAgI2hpZGUgPSBmb28kY291bnQgPCA1MCwKICAgICAgICAgY2V4ID0gMC43CikKCmBgYApUaGlzIGdyYXBoIGNhbiBoZWxwIHlvdSB0byBrbm93IHdoZXJlIHlvdSBjYW4gZmluZCBEUy4gCkZvciBleGFtcGxlIDogCi0gTW9zdCBvZiB0aGUgYmFjaGVsb3IncyBkZWdyZWUgYXJlIG5vdCBEUwotIEEgZ29vZCBTb2Z0d2FyZSBEZXZlbG9wZXIgd2l0aCBhIERvY3RvcmFsIGRlZ3JlZSBjYW4gYmUgYXMgRFMuIE90aGVyd2lzZSwgaXQncyBub3QgYSBEUy4gIAoKIyMgSG93IGNhbiB5b3UgZm9ybSB5b3VyIGRhdGEgc2NpZW50aXN0ID8gCgojIyMgU2tpbGxzCmBgYHtyfQpyZWNvbW1lbmRhdGlvbnMgPC0gU3VydmV5ICU+JSAKICAjIFJlbW92ZSBhbnkgbm9uLWVudHJpZXMgZm9yIGVpdGhlciBxdWVzdGlvbgogIGZpbHRlcighV29ya1Rvb2xzU2VsZWN0ID09ICIiKSAlPiUgCiAgZmlsdGVyKCFMYW5ndWFnZVJlY29tbWVuZGF0aW9uU2VsZWN0ID09ICIiKSAlPiUgCiAgIyBTZWxlY3Qgb25seSB0aGUgY29sdW1ucyBmb3IgdGhlIGxhbmd1YWdlIHJlY29tbWVuZGF0aW9ucyBhbmQgbGFuZ3VhZ2UgdXNlCiAgc2VsZWN0KFdvcmtUb29sc1NlbGVjdCwgTGFuZ3VhZ2VSZWNvbW1lbmRhdGlvblNlbGVjdCkgJT4lIAogICMgU3BsaXQgdGhlIGxhbmd1YWdlIHVzYWdlIGNvbHVtbiBhdCB0aGUgY29tbWEKICBtdXRhdGUoV29ya1Rvb2xzU2VsZWN0ID0gc3Ryc3BsaXQoYXMuY2hhcmFjdGVyKFdvcmtUb29sc1NlbGVjdCksICdcXChbXildKywoKlNLSVApKCpGQUlMKXwsXFxzKicsIHBlcmwgPSBUUlVFKSkgJT4lIAogICMgU3BsaXQgYW5zd2VycyBhcmUgbm93IG5lc3RlZCwgbmVlZCB0byB1bm5lc3QgdGhlbQogIHVubmVzdChXb3JrVG9vbHNTZWxlY3QpICU+JSAKICAjIEdyb3VwIGJ5IGxhbmd1YWdlIHVzZWQgYW5kIHRoZW4gYnkgcmVjb21tZW5kYXRpb24KICBncm91cF9ieShXb3JrVG9vbHNTZWxlY3QsIExhbmd1YWdlUmVjb21tZW5kYXRpb25TZWxlY3QpICU+JSAKICAjIFJlbmFtZSB0aGUgY29sdW1ucwogIHJlbmFtZShVc2VkID0gV29ya1Rvb2xzU2VsZWN0LCBSZWNvbW1lbmRlZCA9IExhbmd1YWdlUmVjb21tZW5kYXRpb25TZWxlY3QpICU+JSAKICAjIENvdW50IHRoZSBudW1iZXIgb2YgcmVzcG9uc2VzIGZvciBlYWNoIGxhbmd1YWdlIHVzZS9yZWNvbW1lbmRhdGlvbiBjb21iaW5hdGlvbgogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGZpbHRlcihjb3VudCA+MzAwKSAKICAKCiMgRGlzcGxheSB0aGUgcmVzdWx0cwpyZWNvbW1lbmRhdGlvbnMkVXNlZCA9IGFzLmZhY3RvcihyZWNvbW1lbmRhdGlvbnMkVXNlZCkKcmVjb21tZW5kYXRpb25zID0gcmVjb21tZW5kYXRpb25zICU+JQogIGRyb3BsZXZlbHMoKQpgYGAKCmBgYHtyfQpjaXJjb3MuY2xlYXIoKQpjaG9yZERpYWdyYW0ocmVjb21tZW5kYXRpb25zLGFubm90YXRpb25UcmFjayA9ICJncmlkIiwscHJlQWxsb2NhdGVUcmFja3MgPSAxKQpjaXJjb3MudHJhY2tQbG90UmVnaW9uKHRyYWNrLmluZGV4ID0gMSwgcGFuZWwuZnVuID0gZnVuY3Rpb24oeCwgeSkgewogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQogIHlsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInlsaW0iKQogIHNlY3Rvci5uYW1lID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJzZWN0b3IuaW5kZXgiKQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAuMSwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpLCBjZXg9LjYpCiAgIyBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2sucGVyY2VudGFnZSA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikKfSwgYmcuYm9yZGVyID0gTkEpCmBgYApBcyB5b3UgY2FuIHNlZSwgbW9zdCBvZiB0aGVtIHVzZSBQeXRob24gYW5kIFIuIElmIHRoZXkgaGF2ZSB0byByZWNvbW1hbmQgaXQsIG1vc3Qgb2YgdGhlbSBjaG9vc2UgUHlodG9uLiAKVGhlIGNpcmxlIHNob3cgdGhhdCBtb3N0IG9mIHRoZSBwZW9wbGUgd29yayB3aXRoIG90aGVyIHRoYXQgUiBhbmQgcHl0aG9uLCB0aGV5IHJlY29tbWFuZCBpdCBweXRob24gYW5kIFIuIAoKV2UgY2FuIGxvb2sgdXAgd2hpY2ggdGVjaG5vbG9naWVzIHdlcmUgY29uc2lkZXJlZCB0byBiZSB0aGUgbW9zdCBpbXBvcnRhbnQgb24gdGhlIGpvYi4gSGVyZSwgSSBwbG90dGVkIHBvcHVsYXJpdHkgYWdhaW5zdCB1c2VmdWxuZXNzIGFnYWluIHRvIHNlZSB3aGljaCB0ZWNobm9sb2dpZXMgYXJlIHVzZWQgdGhlIG1vc3QgaW4gdGhlIHJlYWwgd29ybGQuCmBgYHtyfQojIEdldCBhbGwgY29sdW1uIG5hbWVzIHRoYXQgYmVnaW4gd2l0aCAiSm9iU2tpbGxJbXBvcnRhbmNlIiBhbmQgZW5kIGluIGEgbGV0dGVyCnBsYXRmb3JtcyA8LSBncmVwKCJeSm9iU2tpbGxJbXBvcnRhbmNlLipbQS16XSQiLCBuYW1lcyhTdXJ2ZXkpLCB2YWx1ZT1UKQoKbmFtZXMgPC0gYygpCnBvcHVsYXJpdGllcyA8LSBjKCkKc2NvcmVzIDwtIGMoKQoKZm9yIChwbGF0Zm9ybSBpbiBwbGF0Zm9ybXMpIHsKICAgIHVzZWZ1bG5lc3MgPC0gU3VydmV5ICU+JQogICAgICAgIGdyb3VwX2J5XyhwbGF0Zm9ybSkgJT4lCiAgICAgICAgY291bnQoKQogICAgCiAgICAjIFBvcHVsYXJpdHkgPSB0aGUgbnVtYmVyIG9mIHBlb3BsZSB3aG8gcmVzcG9uZGVkIHRvIHRoaXMgcXVlc3Rpb24KICAgIHBvcHVsYXJpdHkgPC0gdXNlZnVsbmVzc1tbMl1dWzJdICsgdXNlZnVsbmVzc1tbMl1dWzNdICsgdXNlZnVsbmVzc1tbMl1dWzRdCiAgICAKICAgICMgVXNlZnVsbmVzcyA9IGEgd2VpZ2h0ZWQgYXZlcmFnZSBkZXRlcm1pbmluZyB0aGUgdXNlZnVsbmVzcyBvZiB0aGlzIHBsYXRmb3JtCiAgICBzY29yZSA8LSAodXNlZnVsbmVzc1tbMl1dWzJdICogMiArIHVzZWZ1bG5lc3NbWzJdXVszXSAqIDEuNSArIHVzZWZ1bG5lc3NbWzJdXVs0XSAqIDEpIC8gcG9wdWxhcml0eQogICAgCiAgICBuYW1lcyA8LSBjKG5hbWVzLCBnc3ViKCJKb2JTa2lsbEltcG9ydGFuY2UiLCAiIiwgcGxhdGZvcm0pKQogICAgcG9wdWxhcml0aWVzIDwtIGMocG9wdWxhcml0aWVzLCBwb3B1bGFyaXR5KQogICAgc2NvcmVzIDwtIGMoc2NvcmVzLCBzY29yZSkKfQoKc2NvcmVzX2RmIDwtIGRhdGEuZnJhbWUoCiAgICBQb3B1bGFyaXR5ID0gcG9wdWxhcml0aWVzLAogICAgVXNlZnVsbmVzcyA9IHNjb3JlcywKICAgIE5hbWUgPSBuYW1lcwopCgpnZ3Bsb3Qoc2NvcmVzX2RmLCBhZXMoeCA9IFVzZWZ1bG5lc3MsIHkgPSBQb3B1bGFyaXR5KSkgKwogICAgZ2d0aXRsZSgiSW1wb3J0YW50IFNraWxscyBvbiB0aGUgSm9iIikgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBOYW1lLCBmYW1pbHkgPSAiSGVsdmV0aWNhIiksIG51ZGdlX3kgPSAxMikgCmBgYApXaXRoIHRoaXMgZ3JhcGgsIHdlIGNhbiB1bmRlcnN0YW5kIHRoYXQgUHl0aG9uIGlzIHRoZSBtb3N0IHVzZWZ1bCBhbmQgcG9wdWxhciBza2lsbC4gVGhlIHNlY29uZCBvbmUgaXMgU3RhdHMsIHRoZW4gQmlnRGF0YSwgUiwgU1FMIGFuZCBWaXN1YWxpemF0aW9ucy4gCgpOb3cgeW91IGtub3cgd2hpY2ggc2tpbGxzIGFyZSBpbXBvcnRhbnQgZm9yIHlvdXIgZGF0YSBzY2llbnRpc3QsIHlvdSBuZWVkIHRvIGtub3cgSE9XIHRvIGxlYXJuIGl0LiBZb3UgY2FuIHByb3ZpZGUgdGhlbSBzb21lIHBsYXRlZm9ybS4gTGV0J3Mgc2VlIHRoZSBtb3N0IHVzZWZ1bG5lc3MgOiAKCiMjIyBQbGF0ZWZvcm0KYGBge3J9CiMgR2V0IGFsbCBjb2x1bW4gbmFtZXMgdGhhdCBiZWdpbiB3aXRoICJMZWFybmluZ1BsYXRmb3JtVXNlZnVsbmVzcyIKcGxhdGZvcm1zIDwtIGdyZXAoIl5MZWFybmluZ1BsYXRmb3JtVXNlZnVsbmVzcyIsIG5hbWVzKFN1cnZleSksIHZhbHVlPVQpCgpuYW1lcyA8LSBjKCkKcG9wdWxhcml0aWVzIDwtIGMoKQpzY29yZXMgPC0gYygpCgpmb3IgKHBsYXRmb3JtIGluIHBsYXRmb3JtcykgewogICAgdXNlZnVsbmVzcyA8LSBTdXJ2ZXkgJT4lCiAgICAgICAgZ3JvdXBfYnlfKHBsYXRmb3JtKSAlPiUKICAgICAgICBjb3VudCgpCiAgICAKICAgICMgUG9wdWxhcml0eSA9IHRoZSBudW1iZXIgb2YgcGVvcGxlIHdobyByZXNwb25kZWQgdG8gdGhpcyBxdWVzdGlvbgogICAgcG9wdWxhcml0eSA8LSB1c2VmdWxuZXNzW1syXV1bMl0gKyB1c2VmdWxuZXNzW1syXV1bM10gKyB1c2VmdWxuZXNzW1syXV1bNF0KICAgIAogICAgIyBVc2VmdWxuZXNzID0gYSB3ZWlnaHRlZCBhdmVyYWdlIGRldGVybWluaW5nIHRoZSB1c2VmdWxuZXNzIG9mIHRoaXMgcGxhdGZvcm0KICAgIHNjb3JlIDwtICh1c2VmdWxuZXNzW1syXV1bMl0gKiAwICsgdXNlZnVsbmVzc1tbMl1dWzNdICogMC41ICsgdXNlZnVsbmVzc1tbMl1dWzRdICogMSkgLyBwb3B1bGFyaXR5CiAgICAKICAgIG5hbWVzIDwtIGMobmFtZXMsIGdzdWIoIkxlYXJuaW5nUGxhdGZvcm1Vc2VmdWxuZXNzIiwgIiIsIHBsYXRmb3JtKSkKICAgIHBvcHVsYXJpdGllcyA8LSBjKHBvcHVsYXJpdGllcywgcG9wdWxhcml0eSkKICAgIHNjb3JlcyA8LSBjKHNjb3Jlcywgc2NvcmUpCn0KCnNjb3Jlc19kZiA8LSBkYXRhLmZyYW1lKAogICAgUG9wdWxhcml0eSA9IHBvcHVsYXJpdGllcywKICAgIFVzZWZ1bG5lc3MgPSBzY29yZXMsCiAgICBOYW1lID0gbmFtZXMKKQoKZ2dwbG90KHNjb3Jlc19kZiwgYWVzKHggPSBVc2VmdWxuZXNzLCB5ID0gUG9wdWxhcml0eSkpICsKICAgIGdndGl0bGUoIkVmZmVjdGl2ZW5lc3Mgb2YgTGVhcm5pbmcgTWV0aG9kcyIpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gTmFtZSwgZmFtaWx5ID0gIkhlbHZldGljYSIpLCBudWRnZV95ID0gMjAwKSAKYGBgClNvLCB5b3UgY2FuIHByb3Bvc2UgdGhlbSBLYWdnbGUsIENvdXJzZXMsIFN0YWNrIE92ZXJmbG93IGFuZCBQcm9qZWN0cy4gCgojIyBXaGljaCBkYXRhIHNjaWVudGlzdCBhcmUgaGFwcHkgPyAKCiMjIFdoaWNoIHNhbGFyeSBnaXZlIG9uIHlvdXIgZGF0YSBzY2llbnRpc3QgPwpwcmVkaWN0IHRoZSBzYWxhcnkgKG1vZGVsIHJlZ3Jlc3Npb24pCgoKCg==